/*
 * 信号-槽实现
 * 
 * 槽定义
 *  封装:指针函数,成员函数,仿函数
 *  为函数加上id
 *  使用默认拷贝构造函数和赋值构造函数
 * 
 * 历史:
 *  2020-02-26 姚彧 创建
 */

#ifndef __SLOT_H__
#define __SLOT_H__

#include <functional>

struct Slot
{
    typedef int(*Callback)(void*);
    typedef size_t                      id_type;
    typedef std::function<int(void*)>   callback_type;

    id_type         id;
    callback_type   caller;

    // 函数指针型构造函数
    Slot(const Callback& callback)
    {
        id = get_id((void*)&callback);
        caller = std::bind(callback, std::placeholders::_1);
    }

    // 成员函数型构造函数
    template<typename Klass>
    Slot(int(Klass::* fn)(void*), Klass& obj)
    {
        id = get_id(&obj) + get_id(&fn);
        caller = std::bind(fn, &obj, std::placeholders::_1);
    }

    // 仿函数弄构造函数
    template<typename Klass>
    Slot(Klass& obj)
    {
        id = get_id(&obj);
        caller = std::bind(&(Klass::operator()), &obj, std::placeholders:_1);
    }

    // 比较函数
    inline bool operator==(const Slot& rhs)
    {
        return id == rhs.id;
    }

    // 仿函数
    inline int operator()(void* p)
    {
        return caller(p);
    }


private:
    inline id_type get_id(void* p)
    {
        return (id_type)p;
    }
};

#endif